from tkinter import *
import tkinter.messagebox
import re

class Person:  # 自定义用户类
    def __init__(self, account, pwd, money):
        self.account = account
        self.pwd = pwd
        self.money = money

    def getMoney(self):  # 获取对象的money值，由于在一个包下，
        # 其实可以直接用 ‘对象.money’ 获取
        return self.money

    def saveMoney(self, n):
        self.money += int(n)

    def outputMoney(self, n):
        self.money -= n


class ATMsystem:  # 窗口UI实现类

    def __init__(self):
        self.root = Tk()  # 获取一个窗口实例 root

        self.root.geometry('500x250')  # 设置窗口大小
        self.root.title(' ATM ')  # 设置窗体标题
        self.items = []
        ''' items 用于存储目前root窗口中
                                已经添加了哪些组件 ，清除当前
                                窗口中的控件，只需要遍历items调用自己的
                                destroy（）方法，即可清空窗口'''
        self.model = 0  # 自定义model为当前模式
        self.entrys = []  # 自定义当前’ 输入控件 ‘的列表，
        # 获取输入时，遍历该组件，调用get（）方法即可
        self.accounts = {}  # 保存已注册的用户{account：password,}，只存（账户，密码）键值
        self.account = ''  # 为空时代表并未登录，登录后置为登录账号值
        self.customers = []  # 保存已存在的用户对象们，这里存的是对象值
        self.func = ['1', '2', '3', '4', '5', '6', '7']  # 用于判断功能选择输入是否合法
        self.funcs = {'0': self.start, '1': self.func1, '2': self.func2, '3': self.func3, '4': self.func4, '5': self.func5,
                      '6': self.func6, '7': self.func7}
        '''
        由于python中使用字典可以代替switch语句
        我们直接定义8个函数
        然后根据输入框获取的值，跳转执行对应的方法即可
        start（）- func7（）都是根据功能动态添加UI组件，显示到 root窗口中
        '''

    def start(self, *args):
        self.model = 0
        self.cls()
        frame_show = Frame(self.root, \
                           bg='#FFE4C4', \
                           width=700, \
                           height=200,
                           relief=SUNKEN)
        frame_show.pack(fill=X)
        show = '''
            ******************欢迎来到WoniuATM********************
            *******************请选择操作菜单*********************
            '''
        mes = Message(frame_show, text=show, \
                      bg='#d3fbfb', \
                      fg='red', \
                      font=('华文新魏', 18), \
                      width=700, \
                      relief=SUNKEN)
        mes.pack(fill=X)

        var = tkinter.StringVar()  # 设置Message的内容对象
        text1 = '1.注册 2.登录 3.查询余额 4.存款 5.取款 6.转账 7.取卡'
        var.set(text1)
        if len(args) > 0:
            self.account = args[0]
            var.set('3.查询余额 4.存款 5.取款 6.转账 7.取卡')
        func_list = Message(self.root, textvariable=var, \
                            bg='#d3fbfb', \
                            fg='red', \
                            font=('华文新魏', 14), \
                            width=700, \
                            relief=SUNKEN)
        func_list.pack(fill=X)

        if len(args) > 0:
            self.account = args[0]
            func_list.setvar()
        frame_inpput = Frame(self.root, \
                             bg='#FFE4C4', \
                             width=700, \
                             height=200,
                             relief=SUNKEN)
        frame_inpput.pack(fill=X)

        entry = Entry(frame_inpput, \
                      bg='grey', \
                      font=('华文新魏', 20), \
                      width=25, \
                      relief=SUNKEN)
        entry.pack(fill=X)
        btn1 = Button(frame_inpput, text='提交', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()
        self.items.append(frame_show)
        self.items.append(frame_inpput)
        self.items.append(func_list)
        self.entrys.append(entry)


    def isInAccounts(self, ac):
        if len(self.customers) > 0:
            for i in self.customers:
                if i.account == ac:
                    return True
        return False


    def getInput(self):
        print('modle is :', self.model)
        if self.model == 0:  # 0 是初始页面，model模式为0
            get = self.entrys[0]
            rs = get.get()
            print('获取到的输入是 ：', rs)
            if self.account != '' and str(rs) in ['3', '4', '5', '6', '7']:
                self.funcs[rs]()
            elif str(rs) in ['1', '2'] and self.account == '':
                self.funcs[rs]()
            elif self.account == '' and str(rs) in ['3', '4', '5', '6', '7']:
                answer = tkinter.messagebox.askokcancel('错误', '请先登录 ：' + rs)
            else:
                answer = tkinter.messagebox.askokcancel('错误', '输入有误：' + rs)
        elif self.model == 1:  # 1 是注册页面，model 为 1
            account = str(self.entrys[0].get())
            pwd = str(self.entrys[1].get())
            pattern = re.compile('^[a-z0-9A-Z]+')
            match = pattern.findall(pwd)
            print(self.accounts)
            if len(account) < 5 or len(account) > 15 or not match or len(pwd) < 6 or len(pwd) > 15:  # 不符合规则，清空输入框并提示
                answer = tkinter.messagebox.askokcancel('错误', '账户名或密码不符合规则：\n' + account + ' ' + pwd)
                self.entrys[0].delete(0, END)
                self.entrys[1].delete(0, END)
            elif account in self.accounts:
                answer = tkinter.messagebox.askokcancel('错误', '账户名已存在：\n' + account)
                self.entrys[0].delete(0, END)
                self.entrys[1].delete(0, END)
            else:
                self.accounts[account] = pwd
                answer = tkinter.messagebox.askokcancel('注册', '账户注册成功：\n' + account)
                person = Person(account, pwd, 0)
                self.customers.append(person)
                self.start()
                return
        elif self.model == 2:
            account = str(self.entrys[0].get())
            pwd = str(self.entrys[1].get())
            pattern = re.compile('^[a-z0-9A-Z]+')
            match = pattern.findall(pwd)
            print(self.accounts)
            if len(account) < 5 or len(account) > 15 or not match or len(pwd) < 6 or len(pwd) > 15:  # 不符合规则，清空输入框并提示
                answer = tkinter.messagebox.askokcancel('错误', '账户名或密码不符合规则：\n' + account + ' ' + pwd)
            elif account in self.accounts:
                if pwd != self.accounts[account]:
                    answer = tkinter.messagebox.askokcancel('错误', '密码错误 ：\n' + account)
                else:
                    answer = tkinter.messagebox.askokcancel('登录成功', '登录成功 ：\n' + account + ' ' + pwd)
                    self.start(account, pwd)
                    return
            else:
                answer = tkinter.messagebox.askokcancel('错误', '账户尚未注册 ：\n' + account)
            self.entrys[0].delete(0, END)
            self.entrys[1].delete(0, END)
        elif self.model == 4:
            get = self.entrys[0]
            rs = str(get.get())
            if rs.isnumeric() and int(rs) >= 0:
                for i in self.customers:
                    if i.account == self.account:
                        i.saveMoney(int(rs))
                        answer = tkinter.messagebox.askokcancel('存入金额', '你存入的余额为 ：' + str(int(rs)) + '\n 你所剩的金额为：' + str(
                            i.getMoney()))
                        self.start(self.account)
            else:
                answer = tkinter.messagebox.askokcancel('错误', '输入金额格式有误')
                self.entrys[0].delete(0, END)
        elif self.model == 5:
            get = self.entrys[0]
            rs = str(get.get())
            if rs.isnumeric() and int(rs) >= 0:
                for i in self.customers:
                    if i.account == self.account:
                        k = int(rs)
                        if k > i.getMoney():
                            answer = tkinter.messagebox.askokcancel('错误', '所剩余额不足')
                        else:
                            i.outputMoney(k)
                            answer = tkinter.messagebox.askokcancel('取款金额',
                                                                    '你取出的余额为 ：' + str(int(rs)) + '\n 你所剩的金额为：' + str(
                                                                        i.getMoney()))
                            self.start(self.account)
            else:
                answer = tkinter.messagebox.askokcancel('错误', '输入金额格式有误')
                self.entrys[0].delete(0, END)
        elif self.model == 6:
            account = str(self.entrys[0].get())
            money = str(self.entrys[1].get())
            if money.isnumeric() and int(money) >= 0:
                if not self.isInAccounts(account):
                    answer = tkinter.messagebox.askokcancel('错误', '转账账户不存在:' + account)
                    return
                for i in self.customers:
                    if i.account == self.account:
                        k = int(money)
                        if k > i.getMoney():
                            answer = tkinter.messagebox.askokcancel('错误', '所剩余额不足')
                        else:
                            i.outputMoney(k)
                            answer = tkinter.messagebox.askokcancel('转出金额',
                                                                    '你转出的余额为 ：' + str(int(money)) + '\n 你所剩的金额为：' + str(
                                                                        i.getMoney()))
                            for i in self.customers:
                                if i.account == account:
                                    i.saveMoney(money)
                            self.start(self.account)
                            return
            else:
                answer = tkinter.messagebox.askokcancel('错误', '转账金额有误：' + money)
                self.entrys[0].delete(0, END)


    def func1(self):  # register
        self.cls()
        self.model = 1
        text1 = Message(self.root, text='账号', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text1.pack(fill=X)
        account = Entry(self.root, \
                        bg='grey', \
                        font=('华文新魏', 20), \
                        width=25, \
                        relief=SUNKEN)
        account.pack(fill=X)
        text2 = Message(self.root, text='密码', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text2.pack(fill=X)
        psw = Entry(self.root, \
                    bg='grey', \
                    font=('华文新魏', 20), \
                    width=25, \
                    relief=SUNKEN)
        psw.pack(fill=X)
        btn1 = Button(self.root, text='注册', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()
        self.items.append(text1)
        self.items.append(text2)
        self.items.append(psw)
        self.items.append(account)
        self.items.append(btn1)
        self.entrys.append(account)
        self.entrys.append(psw)


    def func2(self):  # 登录页面
        self.cls()
        self.model = 2
        text1 = Message(self.root, text='账号', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text1.pack(fill=X)
        account = Entry(self.root, \
                        bg='grey', \
                        font=('华文新魏', 20), \
                        width=25, \
                        relief=SUNKEN)
        account.pack(fill=X)
        text2 = Message(self.root, text='密码', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text2.pack(fill=X)
        psw = Entry(self.root, \
                    bg='grey', \
                    font=('华文新魏', 20), \
                    width=25, \
                    relief=SUNKEN)
        psw.pack(fill=X)
        btn1 = Button(self.root, text='登录', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()
        self.items.append(text1)
        self.items.append(text2)
        self.items.append(psw)
        self.items.append(account)
        self.items.append(btn1)
        self.entrys.append(account)
        self.entrys.append(psw)


    def func3(self):  # 查询余额
        for i in self.customers:
            if i.account == self.account:
                answer = tkinter.messagebox.askokcancel('查询余额', '你所剩的余额为 ：' + str(i.getMoney()))
        self.entrys[0].delete(0, END)


    def func4(self):  # 存钱
        self.cls()
        self.model = 4
        text2 = Message(self.root, text='请输入存款金额', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text2.pack(fill=X)
        input_money = Entry(self.root, \
                            bg='grey', \
                            font=('华文新魏', 20), \
                            width=25, \
                            relief=SUNKEN)
        input_money.pack(fill=X)
        btn1 = Button(self.root, text='存入', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()

        self.items.append(text2)
        self.items.append(input_money)
        self.items.append(btn1)
        self.entrys.append(input_money)


    def func5(self):  # 取款
        self.cls()
        self.model = 5
        text2 = Message(self.root, text='请输入取款金额', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text2.pack(fill=X)
        output_money = Entry(self.root, \
                             bg='grey', \
                             font=('华文新魏', 20), \
                             width=25, \
                             relief=SUNKEN)
        output_money.pack(fill=X)
        btn1 = Button(self.root, text='取款', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()

        self.items.append(text2)
        self.items.append(output_money)
        self.items.append(btn1)
        self.entrys.append(output_money)


    def func6(self):  # 转账
        self.cls()
        self.model = 6
        text1 = Message(self.root, text='转账账号', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text1.pack(fill=X)
        account = Entry(self.root, \
                        bg='grey', \
                        font=('华文新魏', 20), \
                        width=25, \
                        relief=SUNKEN)
        account.pack(fill=X)
        text2 = Message(self.root, text='金额', \
                        bg='#d3fbfb', \
                        fg='red', \
                        font=('华文新魏', 14), \
                        width=700, \
                        relief=SUNKEN)
        text2.pack(fill=X)
        money = Entry(self.root, \
                      bg='grey', \
                      font=('华文新魏', 20), \
                      width=25, \
                      relief=SUNKEN)
        money.pack(fill=X)
        btn1 = Button(self.root, text='转账', font=('华文新魏', 14), command=self.getInput)
        btn1.pack()
        self.items.append(text1)
        self.items.append(text2)
        self.items.append(money)
        self.items.append(account)
        self.items.append(btn1)
        self.entrys.append(account)
        self.entrys.append(money)


    def func7(self):  # 注销
        self.cls()
        self.model = 0
        self.account = ''
        answer = tkinter.messagebox.askokcancel('取卡', '退出系统成功 ：')
        self.start()


    def cls(self):
        for item in self.items:
            item.destroy()
        self.items.clear()
        self.entrys.clear()


if __name__ == '__main__':
    s = ATMsystem()
    s.start()  # 开启监听
    s.root.mainloop()  # 开启UI

